<?php defined('SYSPATH') OR die('No direct access allowed.');

//TODO: Function to find images in filesystem which are not related to any database records

class File_Plugin extends WB_FormItem {
	
	protected $directory, $necessary_fields, $chmod, $size, $type, $encrypt_name, $new_name, $primary_key, $valid, $add_value;
	
	public function __construct($name='', $params=array())
	{
		parent::__construct($name, $params, 'file text');
		
		$this->directory		= isset($this->params['directory'])? $this->params['directory'] : NULL;
		$this->necessary_fields	= isset($this->params['necessary_fields']) ? $this->params['necessary_fields'] : array();
		$this->chmod			= isset($this->params['chmod'])? $this->params['chmod'] : 0644;
		$this->size				= isset($this->params['size'])? $this->params['size'] : '2M';
		$this->type				= isset($this->params['type'])? $this->params['type'] : 'pdf,doc,xls';
		$this->encrypt_name		= isset($this->params['encrypt_name'])? $this->params['encrypt_name'] : FALSE;
		$this->primary_key		= isset($this->params['primary_key']) ? $this->params['primary_key'] : 'id';
		$this->valid			= FALSE;
		if ( ! empty($this->params['columns']))
		{
			foreach ($this->params['columns'] as $key=>$val)
			{
				$this->table_columns[$key] = $val;
				$this->form_columns[$key] = $val;
				$this->db_columns[$key] = $val;
			}
		}
		
		$this->db_columns[$this->name.'_del'] = null;
		
		Event::add('wb_db.post_add_item', array($this, 'set_value'));
		Event::add('wb_db.post_delete_item', array($this, 'delete_file'));
	}
	
	public function set_value($value=null, $type=null)
	{	
		if (empty($type))
		{
			$type = 'post_add';
			$value = $this->add_value;
			$id =  Kohana::instance()->wb_db->get_last_id();
			$value[$this->primary_key] =  $id;
		}
		elseif ($type=='add')
		{
			$this->add_value = $value;
			$this->value = '';
			return;
		}
		if ($type=='edit' || $type=='post_add')
		{
			// Set the value to NULL in case any error occurs in uploading, this means the database will not be updated
			$del = isset($value[$this->name.'_del']) ? $value[$this->name.'_del'] : NULL;
			$file = isset($value[$this->name]) ? $value[$this->name] : NULL;
			$this->value = NULL;
			unset($value[$this->name]);
			unset($value[$this->name.'_del']);
			
			if ($del) 
			{
				if ($this->delete_file($del, $value))
				{
					if (get_class($this)=='File_Plugin') Kohana::instance()->user_messages->add(
								Kohana::lang('file_plugin.file_deleted', $this->get_label()), 'info');
					$this->value = '';
				}
				else
				{
					if (get_class($this)=='File_Plugin') Kohana::instance()->user_messages->add(
								Kohana::lang('file_plugin.file_delete_failed', $this->get_label()), 'error');
				}
			}
			
			if (empty($file) || empty($file['name']) || empty($file['size']) || $file['error']==UPLOAD_ERR_NO_FILE)
			{
				//Kohana::log('debug', 'File_Plugin::set_value: '.(isset($file) ? print_r($file, true) : 'File not set'));
				Kohana::instance()->user_messages->add(Kohana::lang('file_plugin.upload_not_sent', $this->get_label()), 'info');
				return;	
			}
			if ( $file['error'] != UPLOAD_ERR_OK)
			{
				switch ($file['error'])
				{
					case UPLOAD_ERR_INI_SIZE: 
						Kohana::instance()->user_messages->add(
							Kohana::lang('file_plugin.upload_err_ini_size', $this->get_label()), 'error');
						break;
					case UPLOAD_ERR_FORM_SIZE: 
						Kohana::instance()->user_messages->add(
							Kohana::lang('file_plugin.upload_err_form_size', $this->get_label()), 'error');
						break;
					case UPLOAD_ERR_PARTIAL: 
						Kohana::instance()->user_messages->add(
							Kohana::lang('file_plugin.upload_err_partial', $this->get_label()), 'error');
						break;
					/*case UPLOAD_ERR_NO_FILE: 
						Kohana::instance()->user_messages->add(
							Kohana::lang('file_plugin.upload_err_no_file', $this->get_label()), 'error');
						break;*/
					case UPLOAD_ERR_NO_TMP_DIR: 
						Kohana::instance()->user_messages->add(
							Kohana::lang('file_plugin.upload_err_no_tmp_dir', $this->get_label()), 'error');
						break;
					case UPLOAD_ERR_CANT_WRITE: 
						Kohana::instance()->user_messages->add(
							Kohana::lang('file_plugin.upload_err_cant_write', $this->get_label()), 'error');
						break;
					case UPLOAD_ERR_EXTENSION: 
						Kohana::instance()->user_messages->add(
							Kohana::lang('file_plugin.upload_err_extension', $this->get_label()), 'error');
						break;
				}
			}
			if ( ! upload::size($file, array($this->size))) 
			{
				Kohana::instance()->user_messages->add(Kohana::lang('file_plugin.upload_too_big', $this->size), 'alert');
				return;	
			}
			if ( ! upload::type($file, explode(',',$this->type)))
			{
				Kohana::instance()->user_messages->add(Kohana::lang('file_plugin.upload_not_allowed', $this->type), 'alert');
				return;	
			}
			
			$this->valid = TRUE;
			if ($this->upload_file($file, $value)) 
			{
				$this->value = $this->new_name;
				if ($type=='post_add')
				{
					Kohana::instance()->db
						->set($this->db_columns[$this->name], $this->value)
						->where($this->primary_key,$id)
						->update($this->db_table);
				}
				if (get_class($this)=='File_Plugin') Kohana::instance()->user_messages->add(
							Kohana::lang('file_plugin.file_uploaded', $this->get_label()), 'info');
			}
			else
			{
				if (get_class($this)=='File_Plugin') Kohana::instance()->user_messages->add(
							Kohana::lang('file_plugin.file_upload_failed', $this->get_label()), 'error');
			}
			
		}
		else parent::set_value($value, $type);
	}
	
	/**
	 * Renders the form element
	 * 
	 * @return string
	 */
	public function render_item()
	{
		$value = is_array($this->value) ? $this->value[$this->name] : $this->value;
		
		$str = $this->prefix;
		$str .= form::label($this->name, $this->label);
		$str .= form::upload($this->name, $this->directory, html::attributes($this->attributes));
		if ( ! empty($value)) 
		{
			$file = url::base().$this->get_dir().$value;
			$str .= '<span class="file_del">'.Kohana::lang('file_plugin.delete').' '.form::checkbox($this->name.'_del', $value).'</span>';
			$str .= '<span class="description">Fájl: '.html::file_anchor($file, $value).'</span>';
		}
		$str .= $this->suffix;
		
		return $str;
	}
	
	/**
	 * Renders the form element
	 * 
	 * @return string
	 */
	public function render_cell()
	{	
		$value = is_array($this->value) ? $this->value[$this->name] : $this->value;
		if (empty($value)) return '&nbsp;';
		
		$file = $this->get_dir().$value;
		return html::file_anchor($file, $value);
		
	}
	
	public function upload_file($file, $upload_values=null)
	{
		if ($this->valid)
		{
			$dir = $this->get_dir('', $upload_values);
			$this->get_new_name($file);
			return upload::save($this->name, $this->new_name, $dir, $this->chmod);
		} 
		else return FALSE;
	}
	
	public function delete_file($file=null, $delete_values=null)
	{
		if ($file==null)
		{
			$values = Kohana::instance()->wb_db->get_last_row();
			$file = isset($values[$this->name]) ? $values[$this->name] : null;
			$delete_values = empty($delete_values) ? $values : $delete_values;
		}
		if ( ! is_string($file)) return FALSE;
		elseif ($file=='') return '';
		
		$dir = $this->get_dir(null, $delete_values);
		return @unlink(DOCROOT.$dir.$file);
	}

	public function get_new_name($file='')
	{
		if ( ! empty($this->new_name)) return $this->new_name;
		if (empty($file) || empty($file['name'])) return NULL;
		
		if ($this->encrypt_name) 
		{
			$name = upload::random_name($file['name']);
		}
		else
		{
			$name = time().$file['name'];
			// Remove spaces from the filename
			$name = preg_replace('/\s+/', '_', $name);
		}
		$this->new_name = $name;
		return $name;
	}
	
	public function get_dir($dir=null, $upload_values=null)
	{
		$dir = empty($dir) ? $this->directory : $dir;
		$upload_values = empty($upload_values) ? $this->value : $upload_values;
		
		if (is_array($upload_values) && preg_match('|{.*}|', (string)$dir))
		{
			$replace = array();
			foreach ($upload_values as $k=>$v) $replace[] = '{'.$k.'}';
			$dir = str_replace($replace, $upload_values, $dir);
			$dir = preg_replace(array('|{.*}|', '|/+|'), array('', '/'), $dir);
		}
		//Kohana::log('info', 'File::get_dir Directory found: '.$dir);
		return $dir;
	}
}

//End of File_Plugin Library